#include "nsConfig.h"

#include <Poco/Util/IniFileConfiguration.h>
#include <Poco/AutoPtr.h>
#include <Poco/Exception.h>
#include <fstream>
#include "misc/Debug.h"

Poco::Mutex* nsConfig::mutex = new( Poco::Mutex );
/*********************************************************/
nsConfig& nsConfig::Instance()
{
	mutex->lock();
	static nsConfig pInstance;
	mutex->unlock();
	return( pInstance );
}
/*********************************************************/
nsConfig::nsConfig()
{
	Debug::Instance() << "Config :: Parsing Configuration file: nameserver.ini" << std::endl;
	reparse();
}
/*********************************************************/
void nsConfig::reparse()
{
	Debug& DEBUG = Debug::Instance();

	// Check if nameserver.ini exists
	std::ifstream	ifile("nameserver.ini");
	if ( ifile.is_open() ) {
		ifile.close();
	} else {
		writeDefaultConfig();
	}

	if ( !parse() ) {
		writeDefaultConfig();
		if ( !parse() ) {
			DEBUG << "Config :: Unable to parse configuration, default values corrupted or couldn't write default nameserver.ini file to disk!" << std::endl;
			throw(std::logic_error("Unable to parse configuration, default values corrupted or couldn't write default nameserver.ini file to disk!"));
		}
	}
}
/*********************************************************/
bool nsConfig::parse()
{
	Debug& DEBUG = Debug::Instance();
	mutex->lock();
	Poco::AutoPtr<Poco::Util::IniFileConfiguration> pConf;
	try {
		// Parse the configuration file
		pConf = new Poco::Util::IniFileConfiguration("nameserver.ini");

		// Get all required values
		pNetworkInterface = pConf->getString("NameServer.NetworkInterface");
		pMulticastGroup = Poco::Net::SocketAddress(pConf->getString("NameServer.NetworkMulticastGroup"));
		pBroadcastFrequency = pConf->getInt("NameServer.BroadcastFrequency");
		pKeepAliveTime = pConf->getInt("NameServer.KeepAliveSendDelay");
		pKeepAliveCheck = pConf->getInt("NameServer.KeepAliveCheckDelay");
		pKeepAliveRemove = pConf->getInt("NameServer.KeepAliveRemoveDelay");

		mutex->unlock();
		return( true );
	} catch(Poco::NotFoundException& e ) {
		DEBUG << "Config :: Missing some Configuration parameters in nameserver.ini!" << std::endl;
		mutex->unlock();
		return( false );
	}
}
/*********************************************************/
void nsConfig::writeDefaultConfig()
{
	mutex->lock();
	std::ofstream file;
	file.open("nameserver.ini");
	file << "; Nameserver configuration parameters" << std::endl << std::endl;
	file << "[NameServer]" << std::endl;
	file << "NetworkInterface = "<< DEFAULT_NET_INTERFACE << std::endl;
	file << "NetworkMulticastGroup = " << DEFAULT_MULTICAST_GROUP << std::endl;
	file << "BroadcastFrequency = " << DEFAULT_BROADCAST_FREQUENCY << std::endl;
	file << "KeepAliveSendDelay = " << DEFAULT_KEEPALIVE_SEND_DELAY << std::endl;
	file << "KeepAliveCheckDelay = " << DEFAULT_KEEPALIVE_CHECK_DELAY << std::endl;
	file << "KeepAliveRemoveDelay = " << DEFAULT_KEEPALIVE_REMOVE_DELAY << std::endl;
	file.close();
	mutex->unlock();
}
/*********************************************************/
unsigned int nsConfig::getKeepAliveRemoveDelay() const
{
	mutex->lock();
	unsigned int time = pKeepAliveRemove;
	mutex->unlock();
	return time;
}
/*********************************************************/
void nsConfig::setKeepAliveRemoveDelay(const unsigned int& time)
{
	mutex->lock();
	pKeepAliveRemove = time;
	mutex->unlock();
}
/*********************************************************/
unsigned int nsConfig::getKeepAliveCheckDelay() const
{
	mutex->lock();
	unsigned int time = pKeepAliveCheck;
	mutex->unlock();
	return time;
}
/*********************************************************/
void nsConfig::setKeepAliveCheckDelay(const unsigned int& time)
{
	mutex->lock();
	pKeepAliveCheck = time;
	mutex->unlock();
}
/*********************************************************/
unsigned int nsConfig::getKeepAliveTime() const
{
	mutex->lock();
	unsigned int time = pKeepAliveTime;
	mutex->unlock();
	return time;
}
/*********************************************************/
void nsConfig::setKeepAliveTime(const unsigned int& kat)
{
	mutex->lock();
	pKeepAliveTime = kat;
	mutex->unlock();
}
/*********************************************************/
unsigned int nsConfig::getBroadcastFrequency() const
{
	mutex->lock();
	unsigned int freq = pBroadcastFrequency;
	mutex->unlock();
	return freq;
}
/*********************************************************/
void nsConfig::setBroadcastFrequency(const unsigned int& freq) 
{
	mutex->lock();
	pBroadcastFrequency = freq;
	mutex->unlock();
}
/*********************************************************/
std::string nsConfig::getNetworkInterface() const
{
	mutex->lock();
	std::string intf = pNetworkInterface;
	mutex->unlock();
	return intf;
}
/*********************************************************/
Poco::Net::SocketAddress nsConfig::getMulticastGroup() const
{
	mutex->lock();
	Poco::Net::SocketAddress addr = pMulticastGroup;
	mutex->unlock();
	return addr;
}
/*********************************************************/
void nsConfig::setNetworkInterface( const std::string& intf )
{
	mutex->lock();
	pNetworkInterface = intf;
	mutex->unlock();
}
/*********************************************************/
void nsConfig::setMulticastGroup( const Poco::Net::SocketAddress& mGroup ) 
{
	mutex->lock();
	pMulticastGroup = mGroup;
	mutex->unlock();
}
/*********************************************************/
nsConfig::~nsConfig()
{
	delete( mutex );
}
/*********************************************************/
